package se581.banker.manager.impl;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import org.apache.log4j.Logger;

import se581.banker.dao.TrackerDao;
import se581.banker.dao.UserAccountDao;
import se581.banker.event.EventFactory;
import se581.banker.event.TrackerEvent;
import se581.banker.manager.AccountTracker;

/**
 * This AccountTracker implementation handles client account update requests
 * 
 * 
 * @author mmichalak
 */
public class UpdateTracker implements AccountTracker {
	static Logger logger = Logger.getLogger(UpdateTracker.class.getName());
	
	int socketPort = -1;
	
	UserAccountDao dao = null;
	

	@Override
	public String processRequest(TrackerEvent ev) {
		logger.debug("Beginning processRequest");
		
		if (ev == null) {
			logger.error("Runtime Error - event is null?????????? ");
			return null;
		}
		
		/*			String id = ev.getId();
		// locs = tracking history; contains each position
		ArrayList<AccountTransaction> locs = null;
		AccountTransaction loc = new AccountTransaction();
		loc.setTick(ev.getTick());
		loc.setTransactionAmt(ev.getTransactionAmt());
		
	locs = dataStore.get(id);
		if (locs == null)
			locs = new ArrayList<AccountTransaction>();
		locs.add(loc); // put on history obj
		dataStore.put(ev.getId(), locs); // put back in map
*/		
		
		dao.update(ev);
		
		//TODO update History table
		
		logger.debug("Account updated: " + ev.toEventLine());
		return null;
	}
	


	@Override
	public void run() {
		logger.debug("Starting UpdateTracker instance on port " + socketPort); 

		try {
			String eventLine;
			  
			  ServerSocket welcomeSocket = new ServerSocket(socketPort);
			  welcomeSocket.setReuseAddress(true);

			  while(true) 
			  {
			     Socket connectionSocket = welcomeSocket.accept();

			     BufferedReader inFromClient =
			        new BufferedReader(
			        new InputStreamReader(
			        connectionSocket.getInputStream()));

			     DataOutputStream outToClient =
			        new DataOutputStream(
			        connectionSocket.getOutputStream());

			    try {
			    	eventLine = inFromClient.readLine();
				} catch (SocketException e) {
					// Client reset socket
					logger.warn("SocketException caught.  Client reset socket.");
				    continue;
				}
				 logger.debug("rec'd:  " + eventLine);
				 
				 /**
				  *  FAILURE LOGIC.  These are sent in by the TCPClient
				  *  If a FAILURE update is received, then end this thread to 
				  *  simulate the thread dies
				  */
				 if (eventLine.indexOf("FAIL") > 0)
					 break;

			     outToClient.writeBytes(eventLine.toUpperCase() + '\n');
			     
			     TrackerEvent ev = EventFactory.createEvent(eventLine);
			     processRequest(ev);
//			     partialFileWriter.writeToFileWOBlanks(ev.toEventLine());
			  }
		} catch (IOException e) {
			logger.error("Error in UpdateTracker thread");
			e.printStackTrace();
		}
	}

	public int getSocketPort() {
		return socketPort;
	}

	public void setSocketPort(int socketPort) {
		this.socketPort = socketPort;
	}



	public void setDao(TrackerDao dao) {
		this.dao = (UserAccountDao)dao;
	}

}
